// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

#nullable enable

using System;
using System.Collections.Generic;

namespace NuGet.Protocol.Model
{
    /// <summary>Represents the result of <see cref="IVulnerabilityInfoResource.GetVulnerabilityInfoAsync(Core.Types.SourceCacheContext, Common.ILogger, System.Threading.CancellationToken)"/></summary>
    /// <remarks>Vulnerability data from a package source typically is spread across multiple files. Therefore, it's
    /// possible for some data to be retrieved successfully, while other data failed. This type allows partial data
    /// to be returned along with error information.</remarks>
    public sealed class GetVulnerabilityInfoResult
    {
        /// <summary>The known package vulnerabilities.</summary>
        /// <remarks>The outer IReadOnlyList represents the number of files the package source split the vulnerability data into.
        /// The IReadOnlyDictionary's key is the package ID.
        /// The inner IReadOnlyList is all of the vulnerabilities known for the package ID.
        /// <para>May be null if no vulnerability data was parsed successfully.</para></remarks>
        public IReadOnlyList<IReadOnlyDictionary<string, IReadOnlyList<PackageVulnerabilityInfo>>>? KnownVulnerabilities { get; }

        /// <summary>Any exceptions while reading vulnerability data.</summary>
        /// <remarks>May be null if no exceptions occurred.</remarks>
        public AggregateException? Exceptions { get; }

        /// <summary>Creates an instance of the class.</summary>
        /// <param name="knownVulnerabilities">The value for <see cref="KnownVulnerabilities"/></param>
        /// <param name="exceptions">The value for <see cref="Exceptions"/></param>
        /// <exception cref="InvalidOperationException">When both knownVulnerabilities and exceptions are null.</exception>
        public GetVulnerabilityInfoResult(
            IReadOnlyList<IReadOnlyDictionary<string, IReadOnlyList<PackageVulnerabilityInfo>>>? knownVulnerabilities,
            AggregateException? exceptions)
        {
            if (knownVulnerabilities == null && exceptions == null)
            {
                throw new InvalidOperationException("The result cannot have null known vulnerabilities and no exceptions");
            }

            KnownVulnerabilities = knownVulnerabilities;
            Exceptions = exceptions;
        }
    }
}
